home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / doom / ldhe-src.0 / ldhe-src / dehacked / source / x11_graphics.cc < prev    next >
C/C++ Source or Header  |  1995-05-09  |  17KB  |  686 lines

  1.  
  2. // The X11 graphics module:
  3.  
  4. // There are lots of bugs and omissions in this code, but hey!  It works! :)
  5.  
  6. #include <stdio.h>
  7. #include <string.h>
  8.  
  9. #include "graphics.h"
  10. #include "pc8x8.font"
  11.  
  12. X11_Graphics:: X11_Graphics() 
  13. {
  14.     keyboard = new X11_Keyboard(&display);
  15.     cursor_on = 1;
  16.  
  17.     display = NULL;
  18.     xwindow = NULL;
  19. }
  20.  
  21. X11_Graphics:: ~X11_Graphics()
  22. {
  23.     if ( display )
  24.         set_grmode(TEXT25);
  25. }
  26.  
  27. int 
  28. X11_Graphics:: ibm_charset(void)
  29. {
  30.     return(1);
  31. }
  32.  
  33. void 
  34. X11_Graphics:: flush(void)
  35. {
  36.     if ( mode == TEXT25 ) {
  37.         TTY_Graphics::flush();
  38.         return;
  39.     }
  40.     XFlush(display);
  41. }
  42.  
  43. void 
  44. X11_Graphics:: setcursor(int on)
  45. {
  46.     if ( cursor_on == on ) {
  47.         // Nothing to do. :)
  48.         return;
  49.     }
  50.     if ( mode != TEXT50 ) {
  51.         TTY_Graphics::setcursor(on);
  52.         return;
  53.     }
  54.     cursor_on = on;
  55.     XPutImage(display, MainWin, cursor_gc, vga_cursor, 0, 0, 
  56.             (cursor.x-1)*FONT_WIDTH, (cursor.y-1)*FONT_HEIGHT, 
  57.                         FONT_WIDTH, FONT_HEIGHT);
  58. }
  59.  
  60. void 
  61. X11_Graphics:: set_default_colors(void)
  62. {
  63.     if ( mode == TEXT25 ) {
  64.         TTY_Graphics::set_default_colors();
  65.         return;
  66.     }
  67.     fg = vga_colors[X11_WHITE+8];
  68.     bg = vga_colors[X11_BLACK+8];
  69.     XSetForeground(display, gc, fg);
  70.     XSetBackground(display, gc, bg);
  71. }
  72.  
  73. void 
  74. X11_Graphics:: set_colors(int bright, int foreground, int background)
  75. {
  76.     if ( mode == TEXT25 ) {
  77.         TTY_Graphics::set_colors(bright, foreground, background);
  78.         return;
  79.     }
  80.  
  81.     if ( bright == BRIGHT )
  82.         bright = 8;
  83.     else
  84.         bright = 0;
  85.  
  86.     switch (background) {
  87.         case    BLACK:    bg = vga_colors[X11_BLACK];
  88.                 break;
  89.         case    BLUE:    bg = vga_colors[X11_BLUE];
  90.                 break;
  91.         case    GREEN:    bg = vga_colors[X11_GREEN];
  92.                 break;
  93.         case    CYAN:    bg = vga_colors[X11_CYAN];
  94.                 break;
  95.         case    RED:    bg = vga_colors[X11_RED];
  96.                 break;
  97.         case    MAGENTA: bg = vga_colors[X11_MAGENTA];
  98.                 break;
  99.         case    YELLOW:    bg = vga_colors[X11_YELLOW];
  100.                 break;
  101.         case    WHITE:    bg = vga_colors[X11_WHITE];
  102.                 break;
  103.         default:    // What color was that??
  104.                 bg = vga_colors[X11_BLACK];
  105.                 break;
  106.     }
  107.     XSetBackground(display, gc, bg);
  108.  
  109.     switch (foreground) {
  110.         case    BLACK:    fg = vga_colors[X11_BLACK+bright];
  111.                 break;
  112.         case    BLUE:    fg = vga_colors[X11_BLUE+bright];
  113.                 break;
  114.         case    GREEN:    fg = vga_colors[X11_GREEN+bright];
  115.                 break;
  116.         case    CYAN:    fg = vga_colors[X11_CYAN+bright];
  117.                 break;
  118.         case    RED:    fg = vga_colors[X11_RED+bright];
  119.                 break;
  120.         case    MAGENTA: fg = vga_colors[X11_MAGENTA+bright];
  121.                 break;
  122.         case    YELLOW:    fg = vga_colors[X11_YELLOW+bright];
  123.                 break;
  124.         case    WHITE:    fg = vga_colors[X11_WHITE+bright];
  125.                 break;
  126.         default:    // What color was that??
  127.                 fg = vga_colors[X11_BLACK+bright];
  128.                 break;
  129.     }
  130.     XSetForeground(display, gc, fg);
  131. }
  132.  
  133. void 
  134. X11_Graphics:: clear(void)
  135. {
  136.     if ( mode == TEXT25 ) {
  137.         TTY_Graphics::clear();
  138.         return;
  139.     }
  140.     clr_grscreen();
  141. }
  142.  
  143. void 
  144. X11_Graphics:: clrbox(int x, int y, int width, int height)
  145. {
  146.     if ( mode == TEXT25 ) {
  147.         TTY_Graphics::clrbox(x, y, width, height);
  148.         return;
  149.     }
  150.     if ( mode == GRAPHICS )
  151.         return;
  152.  
  153.     XSetForeground(display, gc, bg);
  154.     XFillRectangle(display, MainWin, gc,
  155.                 (x-1)*FONT_WIDTH, (y-1)*FONT_HEIGHT,
  156.                     width*FONT_WIDTH, height*FONT_HEIGHT);
  157.     XSetForeground(display, gc, fg);
  158. }
  159.  
  160. void 
  161. X11_Graphics:: clreol(void)
  162. {
  163.     if ( mode == TEXT25 ) {
  164.         TTY_Graphics::clreol();
  165.         return;
  166.     }
  167.     if ( mode == GRAPHICS )
  168.         return;
  169.  
  170.     for ( int i=cursor.x; i<=80; ++i )
  171.         X11_Graphics::putch(' ');
  172. }
  173.  
  174. void 
  175. X11_Graphics:: gotoxy(int x, int y)
  176. {
  177.     if ( mode == TEXT25 ) {
  178.         TTY_Graphics::gotoxy(x,y);
  179.         return;
  180.     }
  181.     if ( mode == GRAPHICS )
  182.         return;
  183.  
  184.     if ( cursor_on ) {
  185.         XPutImage(display, MainWin, cursor_gc, vga_cursor, 0, 0, 
  186.             (cursor.x-1)*FONT_WIDTH, (cursor.y-1)*FONT_HEIGHT, 
  187.                         FONT_WIDTH, FONT_HEIGHT);
  188.     }
  189.     cursor.x=x;
  190.     cursor.y=y;
  191.     if ( cursor_on ) {
  192.         XPutImage(display, MainWin, cursor_gc, vga_cursor, 0, 0, 
  193.             (cursor.x-1)*FONT_WIDTH, (cursor.y-1)*FONT_HEIGHT, 
  194.                         FONT_WIDTH, FONT_HEIGHT);
  195.     }
  196. }
  197.  
  198. void 
  199. X11_Graphics:: putch(int ch)
  200. {
  201.     if ( mode == TEXT25 ) {
  202.         TTY_Graphics::putch(ch);
  203.         return;
  204.     }
  205.     if ( mode == GRAPHICS )
  206.         return;
  207.  
  208.     XPutImage(display, MainWin, gc, pc8x8[(unsigned char)ch], 0, 0, 
  209.             (cursor.x-1)*FONT_WIDTH, (cursor.y-1)*FONT_HEIGHT, 
  210.                         FONT_WIDTH, FONT_HEIGHT);
  211.     if ( cursor.x < 80 )
  212.         ++cursor.x;
  213.     else if ( cursor.y < 50 ) {
  214.         ++cursor.y;
  215.         cursor.x=1;
  216.     }
  217.  
  218.     if ( cursor_on ) {
  219.         XPutImage(display, MainWin, cursor_gc, vga_cursor, 0, 0, 
  220.             (cursor.x-1)*FONT_WIDTH, (cursor.y-1)*FONT_HEIGHT, 
  221.                         FONT_WIDTH, FONT_HEIGHT);
  222.     }
  223. }
  224.  
  225. int 
  226. X11_Graphics:: has_graphics(void)
  227. {
  228.     return(1);
  229. }
  230.  
  231. void 
  232. X11_Graphics:: set_grmode(int newmode)
  233. {
  234.     XColor Orig_colors[256], Blank_colors[256];
  235.     int i;
  236.  
  237.   checkmode:
  238.     switch (newmode) {
  239.         case TEXT25:    if ( mode == TEXT25 )
  240.                     return;
  241.                 XCloseDisplay(display);
  242.                 display=NULL;
  243.                 break;
  244.         case TEXT50:    if ( mode == TEXT50 )
  245.                     return;
  246.                 // If we were in a graphics window...
  247.                 if ( mode == GRAPHICS ) {
  248.                     if ( ! xwindow )
  249.                         break;
  250.                     /* Smoothly blank and restore text50 */
  251.                     for ( i=0; i<256; ++i )
  252.                         Orig_colors[i].pixel = i;
  253.                     XQueryColors(display, vis_colormap, 
  254.                                 Orig_colors, 256);
  255.                     memcpy(Blank_colors, Orig_colors,
  256.                             256 * sizeof(XColor));
  257.                     for ( i=0; i<256; ++i ) {
  258.                         Blank_colors[i].red = 0;
  259.                         Blank_colors[i].green = 0;
  260.                         Blank_colors[i].blue = 0;
  261.                     }
  262.                     XStoreColors(display, vis_colormap, 
  263.                                 Blank_colors, 256);
  264.                     XPutImage(display,MainWin,gc,xwindow,
  265.                         0, 0, 0, 0, 
  266.                         DISPLAY_WIDTH, DISPLAY_HEIGHT);
  267.                     XSetWindowColormap(display, MainWin, 
  268.                                 vga_colormap);
  269.                     XStoreColors(display, vis_colormap, 
  270.                                  Orig_colors, 256);
  271.                     break;
  272.                 }
  273.                 // Create a window to play in...
  274.                 if ( OpenMainWindow(TEXT50) != 0 )
  275.                     return;
  276.                 return;
  277.         case GRAPHICS:    if ( mode == GRAPHICS )
  278.                     return;
  279.                 // If we were in TEXT50 mode, save the window.
  280.                 if ( mode == TEXT50 ) {
  281.                     if ( xwindow )
  282.                         XDestroyImage(xwindow);
  283.                     xwindow = XGetImage(display, MainWin, 
  284.                         0, 0, 
  285.                         DISPLAY_WIDTH, DISPLAY_HEIGHT, 
  286.                             AllPlanes, XYPixmap);
  287.                 } else {
  288.                     // Create a window to play in...
  289.                     if ( OpenMainWindow(GRAPHICS) != 0 )
  290.                         return;
  291.                 }
  292.                 // Set the visual colormap...
  293.                 X11_Graphics::clr_grscreen();
  294.                 if ( vis_colormap != ~0L ) {
  295.                     XSetWindowColormap(display, MainWin, 
  296.                                 vis_colormap);
  297.                 }
  298.                 XFlush(display);
  299.                 break;
  300.         case LASTMODE:    newmode = lastmode;
  301.                 goto checkmode;
  302.         default:    // Huh? 
  303.                 fprintf(stderr,
  304.             "Unknown graphics mode: 0x%.2x\n", newmode);
  305.                 return;
  306.     }
  307.     lastmode = mode;
  308.     mode = newmode;
  309. }
  310.  
  311. void 
  312. X11_Graphics:: set_colormap(struct color colormap[256])
  313. {
  314.     int i;
  315.         XColor xcols[256];
  316.  
  317.     if ( mode == TEXT25 ) {
  318.         return;
  319.     }
  320.  
  321.     /* Create a custom visual colormap, if needed */
  322.     if ( vis_colormap == ~0L ) {
  323.         vis_colormap = XCreateColormap(display, MainWin,
  324.             DefaultVisual(display, XDefaultScreen(display)),
  325.                             AllocAll);
  326.     }
  327.  
  328.     /* Allocate custom colors... */
  329.     for(i=0;i<256;i++)
  330.         xcols[i].pixel = i;
  331.     XQueryColors(display, vis_colormap, xcols, 256);
  332.     for(i=0;i<256;i++) {
  333.         xcols[i].red   = colormap[i].red<<8;
  334.         xcols[i].green = colormap[i].green<<8;
  335.         xcols[i].blue  = colormap[i].blue<<8;
  336.     }
  337.     XStoreColors(display, vis_colormap, xcols, 256);
  338.     XSetWindowColormap(display, MainWin, vis_colormap);
  339. }
  340.  
  341. void 
  342. X11_Graphics:: clr_grscreen(void)
  343. {
  344.     if ( mode == TEXT25 ) {
  345.         return;
  346.     }
  347.     XSetForeground(display, gc, vga_colors[0]);
  348.     XSetBackground(display, gc, vga_colors[0]);
  349.     XFillRectangle(display,MainWin,gc,0,0,DISPLAY_WIDTH,DISPLAY_HEIGHT);
  350.     XSetForeground(display, gc, fg);
  351.     XSetBackground(display, gc, bg);
  352. }
  353.  
  354. #if BYTE_ORDER == LITTLE_ENDIAN
  355. void
  356. X11_Graphics:: expand_8x8font(char smallfont[], char bigfont[])
  357. {
  358.     char smask, bmask, bit;
  359.     int i, j;
  360.  
  361.     // Assuming an 8x8 font...
  362.     for ( i=0; i<8; ++i ) {
  363.         bigfont[i*4] = 0x00;
  364.         for ( smask=0x01, bmask=0x03, j=0; j<4; ++j ) {
  365.             if ( smallfont[i]&smask ) {
  366.                 bit = 0xFF;
  367.             } else {
  368.                 bit = 0x00;
  369.             }
  370.             bigfont[i*4] |= (bit&bmask);
  371.             bmask <<= 2;
  372.             smask <<= 1;
  373.         }
  374.         bigfont[(i*4)+1] = 0x00;
  375.         for ( bmask=0x03, j=0; j<4; ++j ) {
  376.             if ( smallfont[i]&smask ) {
  377.                 bit = 0xFF;
  378.             } else {
  379.                 bit = 0x00;
  380.             }
  381.             bigfont[(i*4)+1] |= (bit&bmask);
  382.             bmask <<= 2;
  383.             smask <<= 1;
  384.         }
  385.     }
  386.     for ( i=0; i<8; ++i ) {
  387.         bigfont[(i*4)+2] = bigfont[i*4];
  388.         bigfont[(i*4)+3] = bigfont[(i*4)+1];
  389.     }
  390. }
  391. #else
  392. void
  393. X11_Graphics:: expand_8x8font(char smallfont[], char bigfont[])
  394. {
  395.     char smask, bmask, bit;
  396.     int i, j;
  397.  
  398.     // Assuming an 8x8 font...
  399.     for ( i=0; i<8; ++i ) {
  400.         bigfont[(i*4)+1] = 0x00;
  401.         for ( smask=0x01, bmask=0x03, j=0; j<4; ++j ) {
  402.             if ( smallfont[i]&smask ) {
  403.                 bit = 0xFF;
  404.             } else {
  405.                 bit = 0x00;
  406.             }
  407.             bigfont[(i*4)+1] |= (bit&bmask);
  408.             bmask <<= 2;
  409.             smask <<= 1;
  410.         }
  411.         bigfont[i*4] = 0x00;
  412.         for ( bmask=0x03, j=0; j<4; ++j ) {
  413.             if ( smallfont[i]&smask ) {
  414.                 bit = 0xFF;
  415.             } else {
  416.                 bit = 0x00;
  417.             }
  418.             bigfont[i*4] |= (bit&bmask);
  419.             bmask <<= 2;
  420.             smask <<= 1;
  421.         }
  422.     }
  423.     for ( i=0; i<8; ++i ) {
  424.         bigfont[(i*4)+2] = bigfont[i*4];
  425.         bigfont[(i*4)+3] = bigfont[(i*4)+1];
  426.     }
  427. }
  428. #endif /* Which Endian? */
  429.             
  430. void 
  431. X11_Graphics:: put_graphics_txt(int x, int y, char *string, 
  432.                             unsigned char color)
  433. {
  434.     char big_char[8*4];
  435.     XImage *BIG_ch;
  436.         
  437.     if ( mode != GRAPHICS ) {
  438.         return;
  439.     }
  440.  
  441.     // Make sure we are still on the screen
  442.     y *= 2;
  443.     if ( y+(FONT_HEIGHT*2) > DISPLAY_HEIGHT )
  444.         return;
  445.  
  446.     // Display the text...
  447.     XSetBackground(display, gc, vga_colors[0]);
  448.     XSetForeground(display, gc, color);
  449.     while ( *string ) {
  450.         // Make sure we have room to display
  451.         if ( x+(FONT_WIDTH*2) > DISPLAY_WIDTH )
  452.             return;
  453.         // Expand the font to 2x2 pixels per bit and display...
  454.         X11_Graphics::expand_8x8font(pc8x8_fontdata[*string], big_char);
  455.         BIG_ch=XCreateImage(display, 
  456.             DefaultVisual(display, XDefaultScreen(display)),
  457.                     1, XYBitmap, 0, big_char,
  458.                     FONT_WIDTH*2, FONT_HEIGHT*2, 8, 2);
  459.         XPutImage(display, MainWin, gc, BIG_ch, 0, 0, x, y, 
  460.                         FONT_WIDTH*2, FONT_HEIGHT*2);
  461.         x += FONT_WIDTH*2;
  462.         ++string;
  463.     }
  464. }
  465.  
  466. void 
  467. X11_Graphics:: drawpoint(int x, int y, unsigned char color)
  468. {
  469.     if ( mode != GRAPHICS ) {
  470.         return;
  471.     }
  472.  
  473.     XSetForeground(display, gc, color);
  474.     XDrawPoint(display, MainWin, gc, x*2, y*2);
  475.     XDrawPoint(display, MainWin, gc, (x*2)+1, y*2);
  476.     XDrawPoint(display, MainWin, gc, x*2, (y*2)+1);
  477.     XDrawPoint(display, MainWin, gc, (x*2)+1, (y*2)+1);
  478. }
  479.  
  480. void
  481. X11_Graphics:: Map_Color(Colormap colormap, XColor *xcol)
  482. {
  483.     /* Most of this code is adapted from 'xv' -- Thanks! :) */
  484.     int ri, gi, bi;            /* The color shades we want */
  485.     int rd, gd, bd;            /* The color shades we have */
  486.     int mdist, close, d;        /* Distance and closest pixel */
  487.     int i, c;
  488.         XColor cmap[NUM_COLORS];
  489.  
  490.     /* Read in the current display colormap */
  491.     for ( i=0; i<NUM_COLORS; ++i ) cmap[i].pixel = i;
  492.     XQueryColors(display, colormap, cmap, NUM_COLORS);
  493.  
  494.     mdist = 1000000; close=0;
  495.     ri = (xcol->red >> 8);
  496.     gi = (xcol->green >> 8);
  497.     bi = (xcol->blue >> 8);
  498.  
  499.     /* Cycle through the colors we have */
  500.     for ( c=0; c<NUM_COLORS; ++c ) {
  501.         rd = ri - (cmap[c].red >> 8);
  502.         gd = gi - (cmap[c].green >> 8);
  503.         bd = bi - (cmap[c].blue >> 8);
  504.         d = rd*rd + gd*gd + bd*bd;
  505.  
  506.         if ( d < mdist ) {
  507.             mdist = d;
  508.             close = c;
  509.         }
  510.     }
  511.     /* Now try to allocate the closest color */
  512.     if ( XAllocColor(display, colormap, &cmap[close]) )  {
  513.         xcol->red = cmap[close].red;
  514.         xcol->green = cmap[close].green;
  515.         xcol->blue = cmap[close].blue;
  516.         xcol->pixel = cmap[close].pixel;
  517.     } else {  /* What do we do here? */
  518.         /* Use it anyway -- Does it matter? :) */
  519.         xcol->red = cmap[close].red;
  520.         xcol->green = cmap[close].green;
  521.         xcol->blue = cmap[close].blue;
  522.         xcol->pixel = cmap[close].pixel;
  523.     }
  524. }
  525.  
  526. int
  527. X11_Graphics:: OpenMainWindow(int newmode)
  528. {
  529.     char *window_Name       = " Linux Doom Hack Editor ";
  530.         char *icon_Name         = PROGNAME;
  531.  
  532.     int i;
  533.     XWMHints                wmhints;
  534.         XClassHint              classhints;
  535.         XSizeHints              sizehints;
  536.         XTextProperty   windowName, iconName;
  537.         XSetWindowAttributes winattr;
  538.     XEvent event;
  539.         XColor xcol;
  540.     XGCValues gcv;
  541.     char *argv[2]={PROGNAME, NULL};
  542.         unsigned long   valuemask;
  543.  
  544. /* The following is a bitmap for the X11 cursor */
  545.     char cursor_bitmap[] = 
  546.         { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
  547.  
  548. /* The following are almost IBM standard color codes, with some slight gamma
  549.  * correction for the dim colors to compensate for bright Xwindow screens.
  550.  */
  551.     struct {
  552.            unsigned char r,g,b;
  553.     } crgb[16]={
  554. {0x00,0x00,0x00},{0x18,0x18,0xB2},{0x18,0xB2,0x18},{0x18,0xB2,0xB2},
  555. {0xB2,0x18,0x18},{0xB2,0x18,0xB2},{0xB2,0x68,0x18},{0xB2,0xB2,0xB2},
  556. {0x68,0x68,0x68},{0x54,0x54,0xFF},{0x54,0xFF,0x54},{0x54,0xFF,0xFF},
  557. {0xFF,0x54,0x54},{0xFF,0x54,0xFF},{0xFF,0xFF,0x54},{0xFF,0xFF,0xFF}};
  558.  
  559.     /* Open our DISPLAY */
  560.     if ( !(display=XOpenDisplay(NULL)) ) {
  561.         fprintf(stderr, "X: Couldn't open display\n");
  562.         return(-1);
  563.     }
  564.  
  565.     /* Make sure all is destroyed if killed off */
  566.     XSetCloseDownMode(display, DestroyAll);
  567.  
  568.     /* Get the default colormap */
  569.     vga_colormap=DefaultColormap(display, XDefaultScreen(display));
  570.  
  571.     /* Allocate custom colors... */
  572.     for(i=0;i<16;i++) {
  573.         xcol.red   = crgb[i].r<<8;
  574.         xcol.green = crgb[i].g<<8;
  575.         xcol.blue  = crgb[i].b<<8;
  576.         if (!XAllocColor(display, vga_colormap, &xcol)) {
  577.             /* Map color to one already on the display */
  578.             Map_Color(vga_colormap, &xcol);
  579.         }
  580.         vga_colors[i] = xcol.pixel;
  581.     }
  582.     vis_colormap = ~0L;
  583.  
  584.     /* Create the main window */
  585.     MainWin = XCreateSimpleWindow(display,
  586.                 RootWindow(display, DefaultScreen(display)), 0, 0,
  587.                         DISPLAY_WIDTH, DISPLAY_HEIGHT, 0, 
  588.                 vga_colors[X11_WHITE], vga_colors[X11_WHITE]);
  589.  
  590.     if (XStringListToTextProperty(&window_Name, 1, &windowName) == 0) {
  591.         fprintf(stderr, "Cannot create window name resource.");
  592.         return(-1);
  593.     }
  594.  
  595.     if (XStringListToTextProperty(&icon_Name, 1, &iconName) == 0) {
  596.         fprintf(stderr, "Cannot create icon name resource.");
  597.         return(-1);
  598.     }
  599.  
  600.     /* Various window manager settings */
  601.         wmhints.initial_state   = NormalState;
  602.         wmhints.input           = True;     
  603.         wmhints.flags = StateHint | InputHint;
  604.  
  605.     /* Set the class for xdhe */
  606.     classhints.res_name     = PROGNAME;
  607.     classhints.res_class    = PROGNAME;
  608.  
  609.         /* Setup the max and minimum size that the window will be */
  610.         sizehints.flags         = PSize | PMinSize | PMaxSize;
  611.         sizehints.min_width     = DISPLAY_WIDTH;
  612.         sizehints.min_height    = DISPLAY_HEIGHT;
  613.         sizehints.max_width     = DISPLAY_WIDTH;
  614.         sizehints.max_height    = DISPLAY_HEIGHT;
  615.  
  616.         /* Now set the window manager properties */
  617.         XSetWMProperties(display, MainWin, &windowName, &iconName,
  618.                 argv, 1, &sizehints, &wmhints, &classhints);
  619.  
  620.         valuemask = CWColormap;
  621.         winattr.colormap = vga_colormap;
  622.  
  623.         /* Check if the server allows backing store */
  624.         if (DoesBackingStore(XDefaultScreenOfDisplay(display)) == Always)
  625.         {
  626.                 /* Ok we want backing store as it is very useful */
  627.                 valuemask |= CWBackingStore;
  628.                 winattr.backing_store = Always;
  629.         } else    /* The keyboard handler needs to do refreshes */
  630.         keyboard->toggle_refresh(1);
  631.  
  632.     XChangeWindowAttributes(display, MainWin, valuemask, &winattr);
  633.  
  634.     /* Set up graphics contexts */
  635.     gcv.graphics_exposures = False;
  636.         if (!(gc = XCreateGC(display, MainWin, GCGraphicsExposures, &gcv))) {
  637.         fprintf(stderr, "X: Couldn't create graphics context.\n");
  638.         return(-1);
  639.     }
  640.     gcv.function = GXinvert;
  641.         if (!(cursor_gc = XCreateGC(display, MainWin, 
  642.                 (GCGraphicsExposures|GCFunction), &gcv))) {
  643.         fprintf(stderr, "X: Couldn't create graphics context.\n");
  644.         return(-1);
  645.     }
  646.  
  647.     /* Initialize the font! */
  648.     for ( i=0; i<256; ++i ) {
  649.         pc8x8[i]=XCreateImage(display, 
  650.             DefaultVisual(display, XDefaultScreen(display)),
  651.                     1, XYBitmap, 0, pc8x8_fontdata[i],
  652.                         FONT_WIDTH, FONT_HEIGHT, 8, 1);
  653.     }
  654.     vga_cursor=XCreateImage(display, 
  655.             DefaultVisual(display, XDefaultScreen(display)),
  656.                     1, XYBitmap, 0, cursor_bitmap,
  657.                         FONT_WIDTH, FONT_HEIGHT, 8, 1);
  658.  
  659.     Event_mask =    KeyPressMask | KeyReleaseMask |
  660.                         ButtonPressMask | ButtonReleaseMask |
  661.                         PointerMotionMask |
  662.                         ExposureMask | StructureNotifyMask;
  663.     XSelectInput(display, MainWin, Event_mask);
  664.  
  665.     /* Actually map the main window */
  666.     XMapWindow(display, MainWin);
  667.  
  668.     /* Start up our VGA colormap */
  669.     XSetWindowColormap(display, MainWin, vga_colormap);
  670.  
  671.     /* Loop, waiting for our window to be mapped */
  672.     do {
  673.         /* Get the next event */
  674.         XNextEvent(display, &event);
  675.     }
  676.     while (event.type != MapNotify);
  677.  
  678.     /* Clear the display and show the cursor */
  679.     lastmode = mode;
  680.     mode = newmode;
  681.     clr_grscreen();
  682.     undercursor = NULL;
  683.     gotoxy(1, 1);
  684.     return(0);
  685. }
  686.